
pub fn use_lifetime(){
    use_annotation_for_function_signature();
    use_ann_in_struct();
    test_lifetime();
    move_and_ref();
}

fn longer<'a>(x: &'a str, y: &'a str) -> &'a str{
    if x.len() > y.len(){
        x
    } else{
        y
    }
}
fn use_annotation_for_function_signature(){
    let r;
    {
        let x = String::from("hello");
        let y = String::from("worlda");
        r = longer(x.as_str(), y.as_str());
        println!("r : {}", r);
    }
}

fn use_ann_in_struct(){
    struct Str<'a> {
        content: &'a str
    } 
    let s1 = String::from("hello"); 
    let s = Str{ 
        content : s1.as_str() 
    }; 
    println!("s.content = {}", s.content); 
} 

fn move_and_ref(){
    {
        fn move_to(s: String){
            println!("print in func:{}", s);
            //drop the String of s
        }
        let s = String::from("hello");
        println!("{}", s);
        move_to(s); // move the s-> arg-s of f
        //println!("{}",s); //compile error
    }
    {
        fn ref_to(s: &String){
            println!("print in func:{}", s);
            //not drop the String of s, because the ref of String
        }
        let s = String::from("hello");
        println!("before ref_to {}", s);
        ref_to(&s);
        println!("after ref_to, also can use the s: {}", s);
    }
}

// annotation lifetime
// static  lifetime : "abc" ==> &'static str

fn test_lifetime(){
    let s = String::from("Hello");
    {
        let a = s;
        let _b = print(&a);
    }
    //print(&s);
}
fn print<'a>(x: &'a str) -> &'a str{
    println!("x:{}", x);
    x
}
